using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Kopain
{
    public partial class FormShowNoteInfo : FormBase
    {

#region Private properties.

        NoteType _note;

        private NoteRoot _noteRoot;

        private ChangesType _changes;

#endregion  //Private properties.

#region Public properties.

        [Flags]
        public enum ChangesType
        {
            Title, 
            File
        }

        public ChangesType Changes
        {
            get { return _changes; }
        }
	
#endregion  //Public properties.

#region Constructor.

        public FormShowNoteInfo( NoteType note, NoteRoot noteRoot )
        {
            _note = note;
            _noteRoot = noteRoot;

            InitializeComponent();
        }

#endregion  //Constructor.

#region Event sinks.

        private void FormShowNoteInfo_Load( object sender, EventArgs e )
        {
            lblID.Text = _note.id;
            lblGlobalPath.Text = _noteRoot.path;
            txtTitle.Text = _note.title;
            txtFile.Text = _note.file;
        }

        private void btnBrowse_Click( object sender, EventArgs e )
        {
            BrowseForFile();
        }

        private void btnOK_Click( object sender, EventArgs e )
        {
            this.Close();
        }

        private void btnCancel_Click( object sender, EventArgs e )
        {
            this.Close();
        }

        private void FormShowNoteInfo_FormClosing( object sender, FormClosingEventArgs e )
        {
            if( DialogResult.OK == this.DialogResult )
            {
                CommitChanges();
            }
        }

#endregion  //Event sinks.

#region Private methods.

        /// <summary>This method shows a savefile dialogue to set the new filename of the Note.
        /// </summary>
        private void BrowseForFile()
        {
            using( SaveFileDialog dlg = new SaveFileDialog() )
            {
                dlg.CreatePrompt = true;
                dlg.DefaultExt = Constant.DefaultFullExtension;
                dlg.FileName = txtFile.Text;
                dlg.OverwritePrompt = true;
                if( DialogResult.OK == dlg.ShowDialog(this) ){
                    txtFile.Text = dlg.FileName;
                }
            }
        }

        /// <summary>This method commits the changes made to the form if the dialogue result says so.
        /// It sets the _changes property of the form.
        /// </summary>
        private void CommitChanges()
        {
            _changes = 0; //  Can this be changed to something like "None"?
            _changes |= ( CommitChanges_Title() ? ChangesType.Title : 0);
            _changes |= (CommitChanges_File() ? ChangesType.File : 0);
        }

        /// <summary>This method commits the changes done to the Title control.
        /// </summary>
        /// <returns>True if the Title was updated.</returns>
        private bool CommitChanges_Title()
        {
            string origTitle = _note.title;
            string newTitle = txtTitle.Text.Trim();
            bool titleUpdated = origTitle != newTitle;
            if( titleUpdated )
            {
                _note.title = newTitle;
            }
            return titleUpdated;
        }

        /// <summary>This method commits all changes done to the File control/value.
        /// </summary>
        /// <returns>True if the File was updated.</returns>
        private bool CommitChanges_File()
        {
            bool fileUpdated = false;
            string origFilename = _note.file;
            //  Store the original filename with path in a variable.  The caveat here is that if the original filename
            //  is blank then we don't have a path.  So set to blank.
            string origFilenameWPath = ("" == origFilename ? "" : _note.FileWithPath( _noteRoot ));
            bool isAbsoluteOrigPath = (origFilename == origFilenameWPath);
            string newFilename = txtFile.Text.Trim();
            //  Save a temporary flag for if the string the user wrote in the Filename control is a full path.  There is a caveat
            //  when the control is blank, then the note's text should be stored in the Savefile and we set the 
            //  newFilenameWPath to blank too.
            bool isAbsoluteNewPath = ("" == newFilename ? true : "" != Path.GetDirectoryName( newFilename ));
            string newFilenameWPath = (isAbsoluteNewPath ? newFilename : _noteRoot.path + newFilename);
            
            //  Commit any changes.
            //  There are three kinds of changes.  From inline to a subfile, from a subfile to inline and from one subfile to another.
            //
            if( isAbsoluteOrigPath ? origFilenameWPath != newFilename : origFilename != newFilename )  //  If the filename is changed.
            {
                fileUpdated = true;

                if( "" == origFilename ) //  If the text was stored inline to start with but should now be stored as a subfile.
                {
                    if( DialogResult.Yes == MessageBox.Show( this,
                        string.Format( "Do you really want to move the text out of the savefile and into {0}?", newFilename ), "Kopain - Change file name",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1 ) )
                    {
                        bool removeFile = false;

                        //  Remove the target file if it exists and the user wants so.
                        if( File.Exists( newFilenameWPath ) )
                        {
                            removeFile =
                                (DialogResult.Yes == MessageBox.Show( this,
                                "The file already exists.  Do you want to overwrite it?", "Kopain - Remove file",
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2 ));
                            if( !removeFile )
                            {
                                return false;
                            }
                        }

                        File.WriteAllText( newFilenameWPath, _note.Data );
                        _note.Data = "";
                        _note.file = newFilename;
                    }
                }

                else if( "" == newFilename )    //  The text was in a subfile at first but should now be stored inline.
                {
                    if( DialogResult.Yes == MessageBox.Show( this,
                        "Do you really want to store the text in the savefile?", "Kopain - Change file name",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1 ) )
                    {
                        _note.Data = File.ReadAllText( origFilenameWPath );
                        _note.file = "";
                        if( DialogResult.Yes == MessageBox.Show( this,
                            "Do you want to remove the original file?", "Kopain - Remove original file",
                            MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2 ) )
                        {
                            File.Delete( origFilenameWPath );
                        }
                        else
                        {
                            return false;
                        }
                    }
                }

                else //  The subfile has changed name.
                {
                    if( DialogResult.Yes == MessageBox.Show( this,
                        string.Format( "Do you really want to change the file name to {0}?", newFilename ), "Kopain - Change file name",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1 ) )
                    {
                        //  Check if the new file already exits.  If it does, ask the user to bail out.
                        //
                        if( File.Exists( newFilenameWPath ) )
                        {
                            if( DialogResult.Yes != MessageBox.Show( this,
                                "The new filename is already in use.\r\nDo you want to overwrite it?", "Kopain - error",
                                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) )
                            {
                                return false;
                            }
                        }

                        //  Change the name of the file and update the Savefile with the new file name.
                        //  The target file might exist so we delete it to be safe.  There was a question earlier that confirmed this with the user.
                        //  There is one last check though, if the user changes from a file to the same file - for instance through removing
                        //  the path of the filenamewpath the delete/move does not work; so don't do in those cases.
                        if( newFilenameWPath != origFilenameWPath )
                        {
                            File.Delete( newFilenameWPath );
                            File.Move( origFilenameWPath, newFilenameWPath );
                        }
                        _note.file = newFilename;
                    }
                }
            }

            return fileUpdated;
        }

#endregion  //Private methods.

    }
}